package com.kyg.tjtoolmanager.controller;

import com.kyg.tjtoolmanager.App;
import com.kyg.tjtoolmanager.db.SQLiteUtils;
import com.kyg.tjtoolmanager.module.Goods;
import com.kyg.tjtoolmanager.utils.SpeechUtil;
import com.kyg.tjtoolmanager.utils.Utils;
import io.netty.util.internal.StringUtil;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.function.UnaryOperator;

/**
 * 借取流程
 * 1.按名称查询物品信息，在左侧查询列表中显示，工作人员根据物品位置拿取
 * 2.使用扫描枪或读写器读取物品条码或标签，加入待领用清单
 * 3.双击查询清单，将物品加入待领用列表
 * 4.双击待领用清单，可删除物品
 * 5.待领用清单中未扫描到的物品置为灰色
 * 6.领用接口只推送已扫描到标签的物品。
 * 7.小库房物品，调用开门授权接口
 */
public class BorrowController extends GetGoodsController {

    @FXML
    HBox hTop;
    @FXML
    HBox hList;
    @FXML
    TextField fieldName;
    @FXML
    TextArea areaScan;
    @FXML
    TableView<Goods> tbSearchList, tbBorrowList;
    @FXML
    VBox vbox1, vbox2;
    @FXML
    TableColumn<Goods, String> tbcIndex1, tbcPicture1, tbcName1, tbcNum1, tbcAddress1, tbcStatus1, tbcRemark1;
    @FXML
    TableColumn<Goods, String> tbcIndex2, tbcPicture2, tbcName2, tbcNum2, tbcAddress2, tbcStatus2, tbcRemark2;
    private ObservableList<Goods> borrowGoodsList = FXCollections.observableArrayList();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        super.initialize(location, resources);
        tbcIndex1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().index + "");
                return name;
            }
        });
        // 设置imageCol的单元格值获取器
        Callback<TableColumn<Goods, String>, TableCell<Goods, String>> cellFactory = (col) -> {
            final TableCell<Goods, String> cell = new TableCell<>() {
                private final ImageView imageView = new ImageView();

                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);

                    if (!empty && item != null) {
                        try {
                            Image image = Utils.base64StringToImage(item);
                            imageView.setFitHeight(50);
                            imageView.setPreserveRatio(true);
                            setGraphic(imageView);
                            imageView.setImage(image);
                        } catch (IllegalArgumentException e) {
                            System.out.println("Invalid Base64 string." + e.getMessage());
                        }
                    } else {
                        setText(null);
                        setGraphic(null);
                    }
                }
            };
            return cell;
        };
        tbcPicture1.setCellFactory(cellFactory);
        tbcPicture1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().picture);
                return name;
            }
        });
        tbcName1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().name);
                return name;
            }
        });
        tbcNum1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getNumber());
                return name;
            }
        });
        tbcAddress1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getAddress());
                return name;
            }
        });
        tbcStatus1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getGoodsStatus());
                return name;
            }
        });
        tbcRemark1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().remark);
                return name;
            }
        });
        tbSearchList.setRowFactory(readerTableView -> {
            TableRow<Goods> row = new TableRow<>();
            row.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent mouseEvent) {
                    if (mouseEvent.getClickCount() == 2 && !row.isEmpty()) {
                        Goods object = row.getItem();
                        List<Goods> goodsList = new ArrayList<>();
                        goodsList.add(object);
                        //TODO 带门禁的小库房才可添加至待领用列表。其他物品需扫码或读标签后，添加至领用列表
                        insertToBorrowList(goodsList, false);
                        SQLiteUtils.insertLog("tableview click " + object.toString());
                    }
                }
            });
            return row;
        });

        tbcIndex2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().index + "");
                return name;
            }
        });
        // 设置imageCol的单元格值获取器
        tbcPicture2.setCellFactory(cellFactory);
        tbcPicture2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().picture);
                return name;
            }
        });
        tbcName2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().name);
                return name;
            }
        });
        tbcNum2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getNumber());
                return name;
            }
        });
        tbcAddress2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getAddress());
                return name;
            }
        });
        tbcStatus2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().getGoodsStatus());
                return name;
            }
        });
        tbcRemark2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Goods, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Goods, String> param) {
                SimpleStringProperty name = new SimpleStringProperty(param.getValue().remark);
                return name;
            }
        });
        tbBorrowList.setRowFactory(readerTableView -> {
            TableRow<Goods> row = new TableRow<>();
            row.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent mouseEvent) {
                    if (mouseEvent.getClickCount() == 2 && !row.isEmpty()) {
                        Goods object = row.getItem();
                        tbBorrowList.getItems().remove(object);
                        //重新排列序号
                        for (int i = 0; i < tbBorrowList.getItems().size(); i++) {
                            tbBorrowList.getItems().get(i).index = i + 1;
                        }
                        SQLiteUtils.insertLog("tableview double click " + object.toString());
                    }
                }
            });
            return row;
        });

        areaScan.setTextFormatter(new TextFormatter<>(new UnaryOperator<TextFormatter.Change>() {

            @Override
            public TextFormatter.Change apply(TextFormatter.Change change) {
                String input = change.getText();
                if (input == null || input.isEmpty()) {
                    SQLiteUtils.insertLog("areaScan input is null or empty");
                    return change;
                }
                SQLiteUtils.insertLog("areaScan 扫描结果：" + input);
                if (input.equals("\n")) {
                    SQLiteUtils.insertLog("areaScan 换行符");
                    onCodeSearchClick();
                }
                return change;
            }
        }));
    }

    @Override
    public void onShow() {
        super.onShow();
        SpeechUtil.textToSpeech("请将待借物品放置在工作台读写器上，或使用扫描枪扫描条码");
        double rootW = rootLayout.getWidth();
        double rootH = rootLayout.getHeight();
        SQLiteUtils.insertLog("Borrow onShow W:" + rootW + " H:" + rootH);
        double listW = (rootW - 50) / 2;
        double listH = rootH - 150;
        SQLiteUtils.insertLog("Borrow onShow listW:" + listW + " listH:" + listH);
//        vbox1.setPrefWidth(listW);
//        vbox1.setPrefHeight(listH);
//        vbox2.setPrefWidth(listW);
//        vbox2.setPrefHeight(listH);
        tbSearchList.setPrefWidth(listW);
        tbSearchList.setPrefHeight(listH);
        tbBorrowList.setPrefWidth(listW);
        tbBorrowList.setPrefHeight(listH);
    }

    @FXML
    protected void onSearchClick() {
        String name = fieldName.getText().toString().trim();
        if (StringUtil.isNullOrEmpty(name)) {
            return;
        }
        getGoodsByName(name, new GoodsDataCallback() {
            @Override
            public void onSuccess(List<Goods> goodsList) {
                tbSearchList.getItems().clear();
                for (int i = 0; i < goodsList.size(); i++) {
                    goodsList.get(i).index = i + 1;
                }
                tbSearchList.getItems().addAll(goodsList);
            }
        });
    }

    @FXML
    protected void onBorrowClick() {
        List<Goods> currentList = tbBorrowList.getItems();
        if (currentList.size() == 0) {
            SpeechUtil.textToSpeech("未添加领用物品");
            return;
        }


    }

    /**
     * 条码查询
     */
    @FXML
    protected void onCodeSearchClick() {
        String code = areaScan.getText().toString().trim();
        if (StringUtil.isNullOrEmpty(code)) {
            return;
        }
        String[] codes = code.split("\n");
        getGoodByScanCode(codes[codes.length - 1], false);
    }

    public void insertToBorrowList(List<Goods> goodsList, boolean isReader) {
        super.insertToBorrowList(goodsList, isReader);
        List<Goods> currentList = tbBorrowList.getItems(); //当前列表中所有数据
        /**
         * 读写器读取到物品信息
         * 1.将列表中标签数据删除
         * 2.加入新获取的标签列表
         */
        if (isReader) {
            SQLiteUtils.insertLog("读写器 insertToBorrowList 旧数据个数：" + currentList.size());
            for (int i = 0; i < lastTags.size(); i++) {
                String tagCode = lastTags.get(i);
                for (int j = 0; j < currentList.size(); j++) {
                    if (tagCode.equals(currentList.get(j).code_num)) {
                        tbBorrowList.getItems().remove(currentList.get(j));
                        currentList.remove(j);
                        break;
                    }
                }
            }
        }
        List<Goods> needAddList = new ArrayList<>();       //需要加入的数据
        int length = currentList.size();
        SQLiteUtils.insertLog("insertToBorrowList 表数据个数：" + currentList.size());
        for (int i = 0; i < goodsList.size(); i++) {
            Goods goods = goodsList.get(i);
            boolean isExist = false;
            for (int j = 0; j < currentList.size(); j++) {
                if (goods.id == currentList.get(j).id) {
                    isExist = true;
                }
            }
            if (!isExist) {
                needAddList.add(goods);
                goodsList.get(i).index = length + needAddList.size();
            }
        }
        tbBorrowList.getItems().addAll(needAddList);
        if (needAddList.size() == 0) {
            SpeechUtil.textToSpeech("已存在该物品信息");
        }
    }

    @FXML
    protected void onClearTextClick() {
        areaScan.setText("");
    }

    @Override
    public void onClose() {
        super.onClose();
    }
}
